package org.wisigoth.chat.client.jabber;

import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;

import org.xml.sax.Attributes;

public class Packet {

	public Packet(String element) {
		this.setElement(element);
	}

	public Packet(String element, String value) {
		this.setElement(element);
		this.children.add(value);
	}

	public Packet(Packet parent, String element, String namespace,
			Attributes atts) {
		this.setElement(element);
		this.setNamespace(namespace);
		this.setParent(parent);

		// Copy attributes into hashtable
		for (int i = 0; i < atts.getLength(); i++) {
			this.attributes.put(atts.getQName(i), atts.getValue(i));
		}
	}

	Packet parent;

	public Packet getParent() {
		return this.parent;
	}

	public void setParent(Packet parent) {
		this.parent = parent;
		if (parent != null) {
			parent.children.add(this);
		}
	}

	LinkedList children = new LinkedList();

	public LinkedList getChildren() {
		return this.children;
	}

	public Packet getFirstChild(String subelement) {
		Iterator childIterator = this.children.iterator();
		while (childIterator.hasNext()) {
			Object child = childIterator.next();
			if (child instanceof Packet) {
				Packet childPacket = (Packet) child;
				if (childPacket.getElement().equals(subelement)) {
					return childPacket;
				}
			}
		}
		return null;
	}

	public String getChildValue(String subelement) {
		Packet child = this.getFirstChild(subelement);
		if (child == null) {
			return null;
		}
		return child.getValue();
	}

	public String getValue() {
		StringBuffer value = new StringBuffer();
		Iterator childIterator = this.children.iterator();
		while (childIterator.hasNext()) {
			Object valueChild = childIterator.next();
			if (valueChild instanceof String) {
				value.append((String) valueChild);
			}
		}
		return value.toString().trim();
	}

	SessionImpl session;

	public void setSession(SessionImpl session) {
		this.session = session;
	}

	public SessionImpl getSession() {
		if (this.session != null) {
			return this.session;
		}
		if (this.parent != null) {
			return this.parent.getSession();
		}
		return null;
	}

	String namespace;

	public void setNamespace(String name) {
		this.namespace = name;
	}

	public String getNamespace() {
		return this.namespace;
	}

	String element;

	public void setElement(String element) {
		this.element = element;
	}

	public String getElement() {
		return this.element;
	}

	Hashtable attributes = new Hashtable();

	public String getAttribute(String attribute) {
		return (String) this.attributes.get(attribute);
	}

	public void setAttribute(String attribute, String value) {
		if (value == null) {
			this.removeAttribute(attribute);
		} else {
			this.attributes.put(attribute, value);
		}
	}

	public void removeAttribute(String attribute) {
		this.attributes.remove(attribute);
	}

	public void clearAttributes() {
		this.attributes.clear();
	}

	public String getTo() {
		return (String) this.attributes.get("to");
	}

	public void setTo(String recipient) {
		this.setAttribute("to", recipient);
	}

	public String getFrom() {
		return (String) this.attributes.get("from");
	}

	public void setFrom(String sender) {
		this.setAttribute("from", sender);
	}

	public String getType() {
		return (String) this.attributes.get("type");
	}

	public void setType(String type) {
		this.setAttribute("type", type);
	}

	public String getID() {
		return (String) this.attributes.get("id");
	}

	public void setID(String ID) {
		this.setAttribute("id", ID);
	}

	public void writeXML() throws IOException {
		this.writeXML((this.session).getWriter());
	}

	public void writeXML(Writer out) throws IOException {
		out.write("<");
		out.write(this.element);
		Enumeration keys = this.attributes.keys();
		while (keys.hasMoreElements()) {
			String key = (String) keys.nextElement();
			out.write(" ");
			out.write(key);
			out.write("='");
			out.write((String) this.attributes.get(key));
			out.write("'");
		}

		if (this.children.size() == 0) {
			out.write("/>");
			out.flush();
			return;
		}

		out.write(">");
		Iterator childIterator = this.children.iterator();
		while (childIterator.hasNext()) {
			Object child = childIterator.next();
			if (child instanceof String) {
				out.write((String) child);
			} else {
				((Packet) child).writeXML(out);
			}
		}
		out.write("</");
		out.write(this.element);
		out.write(">");
		out.flush();
	}

	@Override
	public String toString() {
		try {
			StringWriter reply = new StringWriter();
			this.writeXML(reply);
			return reply.toString();
		} catch (Exception ex) {
		}
		return "<" + this.element + ">";
	}
}